#include "DispatchMsgService.h"
#include "NetworkInterface.h"
#include "eventtype.h"
#include "events_def.h"
#include <algorithm>

DispatchMsgService* DispatchMsgService::DMS_ = nullptr;
std::queue<iEvent*>DispatchMsgService::response_events_;
pthread_mutex_t DispatchMsgService::queue_mutex_;
NetworkInterface* DispatchMsgService::NTIF_ = nullptr;

DispatchMsgService::DispatchMsgService()
{
	tp == NULL;
}

DispatchMsgService::~DispatchMsgService()
{

}

BOOL DispatchMsgService::open()
{
	svr_exit_ = FALSE;
	thread_mutex_create(&queue_mutex_);//初始化队列的互斥锁
	tp = thread_pool_init();
	return tp ? TRUE : FALSE;
}

void DispatchMsgService::close()
{
	//delete msg_queue_;
	svr_exit_ = TRUE;
	thread_pool_destroy(tp);
	thread_mutex_destroy(&queue_mutex_);
	tp = NULL;
	
	subscribers_.clear();
}

void DispatchMsgService::subscribe(u32 eid, iEventHandler* handler)
{
	LOG_DEBUG("DispatchMsgService::subscribe eid: %u\n", eid);
	T_EventHandlersMap::iterator iter = subscribers_.find(eid);
	if (iter != subscribers_.end())
	{
		T_EventHandlers::iterator hdl_iter = std::find(iter->second.begin(), iter->second.end(), handler);
		if (hdl_iter == iter->second.end()) {
			iter->second.push_back(handler);
		}
	}
	else {
		subscribers_[eid].push_back(handler); 
	}
}

void DispatchMsgService::unsubscribe(u32 eid, iEventHandler* handler)
{
	T_EventHandlersMap::iterator iter = subscribers_.find(eid);
	if (iter != subscribers_.end()) {
		T_EventHandlers::iterator hdl_iter = std::find(iter->second.begin(), iter->second.end(), handler);
		if (hdl_iter != iter->second.end()) {
			iter->second.erase(hdl_iter);
		}
	}
}

i32 DispatchMsgService::enqueue(iEvent* ev) {
	if (ev == NULL) {
		return -1;
	}
	thread_task_t* task = thread_task_alloc(0);

	task->handler = DispatchMsgService::svc;
	task->ctx = ev;

	return thread_task_post(tp, task);
	//return msg_que
}

iEvent* DispatchMsgService::process(const iEvent* ev)
{
	LOG_DEBUG("DispatchMsgService::process -ev: %p\n", ev);
	if (ev == NULL) {
		return NULL;
	}

	u32 eid = ev->get_eid();

	LOG_DEBUG("DispatchMsgService::process -eid: %u\n", eid);

	if (eid == EEVENTID_UNKOWN) {
		LOG_WARN("DispatchMsgService : unknow event id %d\n", eid);
		return NULL;
	}

	//LOG_DEBUG("dispatch ev : %d\n", ev->get_eid());

	T_EventHandlersMap::iterator handlers = subscribers_.find(eid);
	if (handlers == subscribers_.end()) {
		LOG_WARN("DispatchMsgService : no any event handler subscribed %d\n", eid);
		return NULL;
	}

	iEvent* rsp = NULL;
	for (auto iter = handlers->second.begin(); iter != handlers->second.end(); iter++) {
		iEventHandler* handler = *iter;
		LOG_DEBUG("DispatchMsgService : get handler: %s\n", handler->get_name().c_str());

		rsp = handler->handle(ev);//推荐使用多个vector 或 list 返回多个rsp
	}

	return rsp;
}

void DispatchMsgService::svc(void* argv)
{
	DispatchMsgService* dms = DispatchMsgService::getInstance();
	iEvent* ev = (iEvent*)argv;
	if (!dms->svr_exit_) {
		LOG_DEBUG("dispatchmsgservice::svc ...\n");
		iEvent* rsp = dms->process(ev);
		//斟酌
		if (rsp) {
			rsp->dump(std::cout);
			rsp->set_args(ev->get_args());
		}
		else {
			LOG_DEBUG("DispatchMsgService::svc-->process  return nullptr!");
			rsp = new ExitRspEv();
			rsp->set_args(ev->get_args());
		}
		thread_mutex_lock(&queue_mutex_);
		response_events_.push(rsp);
		thread_mutex_unlock(&queue_mutex_);
		LOG_DEBUG("DispatchMsgService::svc is end!\n");
	}
}

DispatchMsgService* DispatchMsgService::getInstance()
{
	if (DMS_ == nullptr) {
		DMS_ = new DispatchMsgService();
	}

	return DMS_;
}

iEvent* DispatchMsgService::parseEvent(const char* message, u32 len, u32 eid) {
	if (!message) {
		LOG_DEBUG("DispatchMsgService::parseEvent - message is NULL, eid : % d\n", eid);
		return nullptr;
	}
	if (eid == EEVENTID_GET_MOBLIE_CODE_REQ) {  // 手机验证码请求
		tutorial::mobile_request mr;
		if (mr.ParseFromArray(message, len)) {
			// 生成一个手机验证码请求事件
			MobileCodeReqEv* ev = new MobileCodeReqEv(mr.mobile());
			return ev;
		}
	}
	// 登录事件
	else if (eid == EEVENTID_LOGIN_REQ) {
		tutorial::login_request lr;
		if (lr.ParseFromArray(message, len)) {
			// 生成一个登录请求事件
			LoginReqEv* ev = new LoginReqEv(lr.mobile(), lr.icode());
			return ev;
		}
	}
	else if (eid == EEVENTID_RECHARGE_REQ) {
		tutorial::recharge_request rr;
		if (rr.ParseFromArray(message, len)) {
			return new RechargeReqEv(rr.mobile(), rr.amount());
		}
	}
	else if (eid == EEVENTID_GET_ACCOUNT_BALANCE_REQ) {
		//return new GetAccountBalanceEv();
	}
	else if (eid == EEVENTID_LIST_ACCOUNT_RECORDS_REQ) {
		//return new ListAccountRecordsReqEv();
	}
	return nullptr;
}

void DispatchMsgService::handleAllResponseEvent(NetworkInterface* networkinterface)
{
	bool done = false;
	while (!done) {
		iEvent* ev = nullptr;
		thread_mutex_lock(&queue_mutex_);  //对任务队列进行加锁
		if (!response_events_.empty()) {
			ev = response_events_.front();
			response_events_.pop();
		}
		else {
			done = true;
		}
		thread_mutex_unlock(&queue_mutex_);
		if (!done) {
			//1. 判断拿出来的是什么事件
			if (ev->get_eid() == EEVENTID_GET_MOBLIE_CODE_RSP) {
				MobileCodeRspEv* mcre = static_cast<MobileCodeRspEv*>(ev);
				LOG_DEBUG("DispatchMsgService::handleAllResponseEven id: %d \n", EEVENTID_GET_MOBLIE_CODE_RSP);

				ConnectSession* cs = static_cast<ConnectSession*>(ev->get_args());
				cs->response = ev;

				//序列化请求数据
				cs->message_len = mcre->ByteSize();
				cs->write_buf = new char[cs->message_len + MESSAGE_HEADLER_LEN];

				memmove(cs->write_buf, MESSAGE_HEADLER_ID, 4);
				*(u16*)(cs->write_buf + 4) = EEVENTID_GET_MOBLIE_CODE_RSP;
				*(i32*)(cs->write_buf + 6) = cs->message_len;
				LOG_DEBUG("DispatchMsgService::handleAllResponseEven write_buf: %s \n", cs->write_buf + MESSAGE_HEADLER_LEN);

				mcre->SerializeToArray(cs->write_buf + MESSAGE_HEADLER_LEN, cs->message_len);
				networkinterface->send_response_message(cs);
			}
			else if (ev->get_eid() == EEVENTID_EXIT_RSP) {
				ConnectSession* cs = static_cast<ConnectSession*>(ev->get_args());
				cs->response = ev;
				networkinterface->send_response_message(cs);
			}
			else if (ev->get_eid() == EEVENTID_LOGIN_RSP) {
				LoginRspEv* lgre = static_cast<LoginRspEv*>(ev);
				LOG_DEBUG("DispatchMsgService::handleAllResponseEven id: EEVENTID_LOGIN_RSP \n");

				ConnectSession* cs = static_cast<ConnectSession*>(ev->get_args());
				cs->response = ev;

				//序列化请求数据
				cs->message_len = lgre->ByteSize();
				cs->write_buf = new char[cs->message_len + MESSAGE_HEADLER_LEN];

				//组装消息头
				memmove(cs->write_buf, MESSAGE_HEADLER_ID, 4);
				*(u16*)(cs->write_buf + 4) = EEVENTID_LOGIN_RSP;
				*(i32*)(cs->write_buf + 6) = cs->message_len;
				lgre->SerializeToArray(cs->write_buf + MESSAGE_HEADLER_LEN, cs->message_len);
				networkinterface->send_response_message(cs);
			}
			else if (ev->get_eid() == EEVENTID_RECHARGE_RSP) {
				RechargeRspEv* rre = static_cast<RechargeRspEv*>(ev);
				LOG_DEBUG("DispatchMsgService::handleAllResponseEven id: EEVENTID_RECHARGE_RSP \n");

				ConnectSession* cs = static_cast<ConnectSession*>(ev->get_args());
				cs->response = ev;

				//序列化请求数据
				cs->message_len = rre->ByteSize();
				cs->write_buf = new char[cs->message_len + MESSAGE_HEADLER_LEN];

				//组装消息头
				memmove(cs->write_buf, MESSAGE_HEADLER_ID, 4);
				*(u16*)(cs->write_buf + 4) = EEVENTID_RECHARGE_RSP;
				*(i32*)(cs->write_buf + 6) = cs->message_len;
				rre->SerializeToArray(cs->write_buf + MESSAGE_HEADLER_LEN, cs->message_len);
				networkinterface->send_response_message(cs);
			}
			else {
				LOG_ERROR("DispatchMsgService::handleAllResponseEvent - unknow event id: %d\n", ev->get_eid());
			}
		}
	}
}